import type {ComponentResolver} from "unplugin-vue-components"
import {isSSR} from "../is-ssr"

/**
 * 生成组件库组件自动按需导入的解析器
 * @param {string} compNameStartsWith 组件名称前缀，组件名称以什么开头，以指定的组件名称前缀开头的组件才会被解析器解析
 * @param {string} from 需要自动按需导入的组件的来源组件库
 * @param {(moduleType: string, compName: string) => string} sideEffects 跟随组件一同导入的附加内容的导入路径，如 CSS 文件，
 * 通过传入一个函数来动态生成跟随组件一同导入的附加内容的导入路径，会向传递进来的函数传递两个参数：moduleType —— 组件使用什么类型的模块导入
 * （commonjs 导入/ esm 导入）；compName —— 需要自动按需导入的组件的名称
 * @returns 组件库组件自动按需导入的解析器
 */
export const genCompLibResolver = (
  compNameStartsWith: string,
  from: string,
  sideEffects: (moduleType: string, compName: string) => string
) => {
  // 导入模块的类型，服务端渲染使用 cjs 模块（commonjs 导入），反之使用 esm 模块（import 导入）
  const moduleType = isSSR() ? "lib" : "es"
  return (): ComponentResolver => {
    return {
      // 指定该解析器对什么类型进行解析
      // 这里指定对组件类型进行解析，然后根据组件名称自动按需导入组件
      type: "component",
      // 解析器处理函数
      // 根据组件名称自动按需导入组件
      resolve: (name: string) => {
        // 判断解析的组件名称是不是当前组件库的
        if (name.startsWith(compNameStartsWith)) {
          return {
            // 要导入的组件名称
            name,
            // 从哪里导入
            from,
            // 根据组件名称自动按需导入组件时，需要一同导入的附加内容
            // 由于组件的样式是打包到了单独的样式文件中，所以还需在这里指定导入组件的样式文件
            sideEffects: sideEffects(moduleType, name),
          }
        }
      },
    }
  }
}
